package com.itheima.service.Impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.itheima.anno.Log;
import com.itheima.common.PageBean;
import com.itheima.dto.EmpDto;
import com.itheima.dto.EmpLoginDto;
import com.itheima.dto.EmpPasswprdDto;
import com.itheima.dto.EmpQueryDto;
import com.itheima.mapper.EmpExprMapper;
import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import com.itheima.pojo.EmpExpr;
import com.itheima.service.EmpService;
import com.itheima.utils.JwtUtils;
import com.itheima.vo.EmpVo;
import com.itheima.vo.JobVo;
import com.itheima.vo.LoginVo;
import com.itheima.vo.SexVo;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class EmpServiceImpl implements EmpService {

    @Autowired
    EmpMapper empMapper;
    @Autowired
    EmpExprMapper empExprMapper;

    @Override
    public PageBean pageQuery(EmpQueryDto dto) {
        //PageBean对象中包含哪些信息？total总条数、rows数据列表
        PageHelper.startPage(dto.getPage(), dto.getPageSize());
        Page<EmpVo> page = (Page<EmpVo>) empMapper.query(dto);
        Long total = page.getTotal();
        List<EmpVo> list = page.getResult();
        return new PageBean(total, list);
    }

    @Override
    @Transactional
    @Log
    public void insert(EmpDto empDto) {
        /*
       1.添加员工的基本信息
       2.添加多条工作经历
        * */
        Emp emp = new Emp();
        BeanUtils.copyProperties(empDto, emp);
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setPassword(DigestUtil.bcrypt("123456"));
        empMapper.insert(emp);

        List<EmpExpr> list = empDto.getExprList();
        list.forEach(empExpr -> {
            empExpr.setEmpId(emp.getId());
            empExprMapper.insert(empExpr);
        });
    }

    @Override
    public EmpVo getById(Integer id) {
        //EmpVo = Emp + List<EmpExpr>

        //1. 根据员工id查询emp信息：Emp
        Emp emp = empMapper.getById(id);
        //2. 根据员工id查询emp_expr信息：List<EmpExpr>
        List<EmpExpr> list = empExprMapper.getByEmpId(id);

        //3. 将 Emp、List<EmpExpr>封装到 Vo中
        EmpVo vo = new EmpVo();
        BeanUtils.copyProperties(emp, vo);
        vo.setExprList(list);

        //4. 返回Vo对象
        return vo;
    }

    @Override
    @Transactional
    public void update(EmpDto dto) {
        //EmpDto = 包含了 Emp ，还包含了工作经历 List<EmpExpr>

        //1. 更新emp表数据
        Emp emp = new Emp();
        BeanUtils.copyProperties(dto, emp); //将dto中员工的基本信息拷贝到emp对象中
        emp.setUpdateTime(LocalDateTime.now());
        empMapper.update(emp);

        //2. 更新emp_expr工作经历
        List<EmpExpr> exprList = dto.getExprList();
        //先删除原来的工作经历，再添加新的工作经历
        empExprMapper.delete(emp.getId());
        exprList.forEach(empExpr -> {
            //添加员工工作经历（注意事项：必须给empId复制）
            empExpr.setEmpId(emp.getId());
            empExprMapper.insert(empExpr);
        });
    }

    @Override
    @Transactional
    public void delete(List<Integer> ids) {
        ids.forEach(integer -> {
            empMapper.delete(integer);
            empExprMapper.delete(integer);
        });
    }

    @Override
    public List<Emp> selectAll() {
        return empMapper.selectAll();
    }

    @Override
    public List<SexVo> sex() {

        return empMapper.sex();
    }

    @Override
    public JobVo job() {

        /*使用hutool工具包*/
        List<SexVo> list = empMapper.Job();
        List<String> names = CollUtil.getFieldValues(list, "name", String.class);
        List<Integer> values = CollUtil.getFieldValues(list, "value", Integer.class);

       /*  //使用stream流实现
        //遍历 List<ItemVo>， 将每个ItemVo的职位名称获取出来，形成一个新的List<String>
        List<String> names = list.stream().map(SexVo::getName).collect(Collectors.toList());
        //遍历 List<ItemVo>， 将每个ItemVo的职位数量获取出来，形成一个新的List<Integer>
        List<Integer> values = list.stream().map(SexVo::getValue).collect(Collectors.toList());*/
        return JobVo.builder().jobList(names).dataList(values).build();
    }

    @Override
    public LoginVo login(EmpLoginDto empLoginDto) {

        //1. 查询是否存在该用户

        Emp emp = empMapper.login(empLoginDto);

        if (emp == null) {
            //用户不存在
            throw new RuntimeException("用户不存在");
        }

        //2. 判断密码是否正确


        //密码错误
        //if (!StrUtil.equals(emp.getPassword(), empLoginDto.getPassword())) {
        if (!DigestUtil.bcryptCheck(empLoginDto.getPassword(), emp.getPassword())) {


            throw new RuntimeException("密码错误");
        }
        // }

        Map<String, Object> map = new HashMap<>();
        map.put("id", emp.getId());
        String jwt = JwtUtils.createJwt(map);
        //3. 登录成功
        return LoginVo.builder()
                .id(emp.getId())
                .username(emp.getUsername())
                .name(emp.getName())
                .token(jwt)
                .build();
    }

    @Override
    public void changePassword(EmpPasswprdDto dto) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        String empId = null;
        try {
            empId = JwtUtils.parseJwt(token).get("id").toString();
        } catch (Exception e) {
            e.printStackTrace();
        }

        Emp emp = empMapper.getById(Integer.valueOf(empId));

        //2. 判断旧密码是否正确   DigestUtil.bcryptCheck( "123456",  加密字符串 )
        if (!DigestUtil.bcryptCheck(dto.getPassword(), emp.getPassword())) {
            throw new RuntimeException("原始密码错误，请重新输入");
        }

        //3. 对新密码加密，更新密码操作
        String bcrypt = DigestUtil.bcrypt(dto.getNewpassword());
        emp.setPassword(bcrypt);
        empMapper.update(emp);
    }

}

